package com.jky.stmall.front.service.impl;

import com.jky.stmall.front.entity.*;
import com.jky.stmall.front.mapper.*;
import com.jky.stmall.front.service.OrderService;
import com.jky.stmall.front.util.MD5Util;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@AllArgsConstructor
public class OrderServiceImpl implements OrderService {
    private OrderMapper orderMapper;
    private OrderDetailMapper orderDetailMapper;
    private AddrMapper addrMapper;
    private CartMapper cartMapper;
    private GoodsMapper goodsMapper;

    private UserMapper userMapper;
    @Override
    @Transactional(
            rollbackFor = Exception.class,
            isolation = Isolation.SERIALIZABLE,
            propagation = Propagation.REQUIRED
    )
    public int add(Order order,Integer[] cartIds) throws Exception {
        /*
        如何生成一个订单
        1.需要数据有哪些
        id：字符串 唯一 不能为空not null =>UUID 分布式数据库中 使用UUID 作为主键
        userId：从Session中取出即可
        addrId：确认订单页面传过来，验证是不是当前用户的

        订单的详情、
        购物车的ID=>查询购物车的信息，包含商品的信息。
        count：验证商品的库存>=购买的数量才可以
        price：直接取
        goodsId：直接取
        orderId：从order中直接取
        2.数据库的操作
        1）先保存订单的信息到order表
        2）保存订单的详情信息到order_detail表
        以上的操作要组成一个事务
        */
        //1.生成UUID作为订单ID
        order.setId(UUID.randomUUID().toString());
        //2.验证地址是当前用户的
        Addr addr=addrMapper.selectById(order.getAddrId());
        if (addr.getUserId()!=order.getUserId()){
            throw new Exception("当前地址不匹配，请重新生成订单");
        }
        //3.保存order到数据库中
        int code = orderMapper.insert(order);
        if (code<=0){
            throw new Exception("订单保存失败"); 
        }
        //4.根据CartsId查询购物车信息
        List<Cart> carts=cartMapper.selectByIds(cartIds);
        if (carts.size()!=cartIds.length){
            throw new Exception("购物车数据不匹配！！");
        }
        //5.验证购物车是否属于当前用户
        for (Cart cart:carts){
            if (cart.getUserId()!=order.getUserId()){
                throw new Exception("购物车数据和当前用户的信息不匹配");
            }
            //6.验证库存
            if (cart.getCount()>cart.getGoods().getCount()){
                throw new Exception("库存不足！！！");
            }
            //7.验证商品的状态哦
            if (cart.getGoods().getStatus()==1){
                throw new Exception("商品已经下架");
/*                //为了保证商品数据的一致性，防止超买超卖情况的出现。提前扣除库存
                //在生成订单，没有支付时，先提前扣除库存（锁定库存）
                //如果用户不支付，取消订单，将库存返还*/

            }
                cart.getGoods().setCount(cart.getGoods().getCount()-cart.getCount());

                code=goodsMapper.update(cart.getGoods());
                if (code<=0){
                    throw new Exception("商品库存扣除失败！！");
                }
        }
        //8.将订单的详情，保存到order_detail表
        List<OrderDetail> orderDetails=new ArrayList<>();
        for (Cart cart: carts) {
            OrderDetail orderDetail=new OrderDetail();
            orderDetail.setOrderId(order.getId());
            orderDetail.setCount(cart.getCount());
            orderDetail.setGoodsId(cart.getGoodsId());
            orderDetail.setPrice(cart.getGoods().getPrice());
            orderDetails.add(orderDetail);
        }
        code =orderDetailMapper.insertBatch(orderDetails);
        if (code!=cartIds.length){
            throw new Exception("订单详情写入失败");
        }
        //删除购物车
        for(Cart cart:carts){
            cartMapper.delete(cart.getId());
        }


        return 1;
    }

    @Override
    public int remove(String id) throws Exception {
        return 0;
    }

    @Override
    public int edit(Order order) throws Exception {
        return 0;
    }

    @Override
    public Order getById(String id) {
        return orderMapper.selectById(id);
    }

    @Override
    public List<Order> getByUserId(Integer userId) {
        return orderMapper.selectByUserId(userId);
    }

    @Override
    @Transactional(
            rollbackFor = Exception.class,
            isolation = Isolation.SERIALIZABLE,
            propagation = Propagation.REQUIRED
    )
    public int pay(String id, Integer userId, String paypwd) throws Exception {

        //1.参数的验证
        Order order=orderMapper.selectById(id);
        if (order==null){
            //订单不存在
            throw new Exception("订单不存在");
        }
        if (order.getStatus()!=0){
            throw new Exception("订单已经支付，请不要重复支付！！");
        }
        if (order.getUserId()!=userId){
            throw new Exception("登录信息发生改变，请重新支付订单！！");
        }
        BigDecimal sum=new BigDecimal(0);
        //2.验证金额  订单中的所有详情 进行累加
        for (OrderDetail orderDetail:order.getOrderDetails()){
            //计算 * 算术运算符 乘法运算只能对数值型进行运算
            sum=sum.add(orderDetail.getPrice().multiply(new BigDecimal(orderDetail.getCount())));

        }
        User user=userMapper.selectById(userId);
        if (user.getMoney().compareTo(sum)==-1){//小于
            throw new Exception("余额不足，请及时充值");
        }
        //3。验证密码
        if (user.getPayPassword()==null){
            throw new Exception("没有设置支付密码,请完善后再进行支付");

        }
        //判断密码是否正确
        String md5PayPwd= MD5Util.getMD5(paypwd+user.getSalt());
/*        System.out.println(md5PayPwd);*/
        if (!user.getPayPassword().equals(md5PayPwd)){
            throw new Exception("支付密码错误！！！");
        }
        //执行支付的操作
        //扣钱
        user.setMoney((user.getMoney().subtract(sum)));
        int code=userMapper.update(user);

        if (code!=1){
            throw new Exception("扣款失败");
        }
        //修改订单的状态
        order.setStatus(1);
        code=orderMapper.update(order);
        if (code!=1){
            throw new Exception("订单状态修改失败");
        }

        return 1;//成功了 yeah！！！
    }
}
